#版本说明：该版本是重要版本， 计算下单量的主要更能已经稳定下来了
# -*- coding: utf-8 -*-
import sys
import asyncio  # 新增
from threading import Thread  # 新增
from PyQt5.QtCore import Qt, QObject, pyqtSignal  # 新增Qt
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                            QHBoxLayout, QLabel, QLineEdit, QPushButton,
                            QTableWidget, QTableWidgetItem, QHeaderView,QMessageBox,QDesktopWidget,QStyleFactory)
from PyQt5.QtGui import QIcon,QFont
from tqsdk import TqApi, TqAuth, TqAccount, TqSim  # 新增TqSim

class CapitalManager(QMainWindow):
    update_signal = pyqtSignal(str)
    connection_signal = pyqtSignal(str, bool)

    def _connect_thread(self):
        try:
            # 修正经纪商代码为官方格式（关键修复）
            self.tq_account = TqAccount("H徽商期货", "155831", "alibaba999")  
            self.api = TqApi(account=self.tq_account,
                           auth=TqAuth("szlwy68", "alibaba999"),
                           _stock=False)
            
            # 延长超时时间为20秒
            # import time
            # timeout = time.time() + 20  # 延长至20秒
            # while not hasattr(self.api._account, '_has_login') or not self.api._account._has_login:
            #     if time.time() > timeout:
            #         raise TimeoutError("连接超时")
            # self.api.wait_update()
            self.macc=self.api.get_account()
            print("已经成功连接天勤账户")
            print("当前账户可用资金：",self.macc.available)
            
            # 修正f-string语法错误
            self.update_signal.emit(f"{self.macc.available:.2f}")  # 新增
            
            # 发射连接成功信号
            self.connection_signal.emit("已连接 (点击断开)", True)
            self.update_capital()  # 启动资金更新线程
            
        except Exception as e:
            self.connection_signal.emit(f"连接失败: {str(e)}", False)

    def handle_connection(self, text, success):
        """处理连接状态更新"""
        self.connect_btn.setText(text)
        self.connect_btn.setEnabled(True)
        if success:
            # 断开原有连接并绑定断开方法
            try:
                self.connect_btn.clicked.disconnect()
            except TypeError:
                pass
            self.connect_btn.clicked.connect(lambda: self.disconnect_tq())
            QApplication.processEvents()
            # 删除下面这行已移除的方法调用
            # self.update_capital()  # <<< 这行需要删除
        else:
            # 重新绑定连接方法（关键修复）
            try:
                self.connect_btn.clicked.disconnect()
            except TypeError:
                pass
            self.connect_btn.clicked.connect(self.connect_tq)

    def closeEvent(self, event):  # 新增窗口关闭事件处理
        self.disconnect_tq()
        event.accept()

   
    def _connect_thread(self):
        try:
            self.tq_account = TqAccount("H徽商期货", "155831", "alibaba999")  
            self.api = TqApi(account=self.tq_account,
                           auth=TqAuth("szlwy68", "alibaba999"),
                           _stock=False)
            
            self.macc=self.api.get_account()
            print("已经成功连接天勤账户")
            print("当前账户可用资金：",self.macc.available)
            
            self.update_signal.emit(f"{self.macc.available:.2f}")  # 保留单次获取
            self.connection_signal.emit("已连接 (点击断开)", True)
            
            # 注释掉自动更新线程的启动
            # self.update_capital()  
            
        except Exception as e:
            self.connection_signal.emit(f"连接失败: {str(e)}", False)

    def __init__(self):
        super().__init__()
        self.setWindowTitle("资金管理系统")
        self.resize(800, 600)
        # 初始化产品数据（关键修复）
        self.products = [
            # 示例数据结构（需要替换为真实数据）
            {
                'name': '螺纹钢',
                'margin': 5000,    # 每手保证金
                'stoploss': 50,    # 单笔止损点数
                'multiplier': 10   # 每点价值
            },
            # 添加更多品种...
        ]
        self.init_ui()

    def init_ui(self):
        # 创建主控件和布局（必须首先完成）
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        layout = QVBoxLayout(main_widget)

        # ==== 创建所有UI组件 ====
        # 连接按钮
        self.connect_btn = QPushButton("连接天勤账户")
        self.connect_btn.clicked.connect(self.connect_tq)
        layout.addWidget(self.connect_btn)

        # 输入区域
        input_layout = QHBoxLayout()
        # 资金输入
        self.capital_input = QLineEdit()
        self.capital_input.setPlaceholderText("正在获取账户资金...")
        self.capital_input.setReadOnly(True)
        input_layout.addWidget(QLabel("账户可用资金:"))
        input_layout.addWidget(self.capital_input)
        
        # 风险比例输入
        self.risk_input = QLineEdit()
        self.risk_input.setPlaceholderText("输入风险比例（%）")
        self.risk_input.setText("20")
        input_layout.addWidget(QLabel("风险比例:"))
        input_layout.addWidget(self.risk_input)
        layout.addLayout(input_layout)

        # 计算按钮
        self.calc_btn = QPushButton("计算开仓量")
        self.calc_btn.clicked.connect(self.calculate)
        layout.addWidget(self.calc_btn)

        # 结果表格
        self.table = QTableWidget()
        self.table.setColumnCount(5)
        self.table.setHorizontalHeaderLabels(["品种", "保证金", "止损金额", "建议开仓量", "最大开仓量"])
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        
        # 添加对齐设置（新增代码）
        from PyQt5.QtCore import Qt
        # 表头左对齐
        self.table.horizontalHeader().setDefaultAlignment(Qt.AlignLeft)
        # 单元格内容左对齐
        self.table.setStyleSheet("QTableWidget::item { text-align: left; }")
        
        layout.addWidget(self.table)

        # 说明标签
        explanation = QLabel("""<span style='color: blue; font-size: 10pt'>
        计算公式说明：<br/>
        1. 最大开仓量 = (账户资金 × 风险比例) / 每手保证金（取整）<br/>
        2. 建议开仓量 = 最大开仓量 // 3
        </span>""")
        explanation.setContentsMargins(5, 5, 5, 10)
        layout.addWidget(explanation)

        # ==== 最后连接信号 ====
        self.connection_signal.connect(self.handle_connection)
        self.update_signal.connect(self.capital_input.setText)

        # 设置布局伸缩比例
        layout.setStretch(0, 0)   # 输入区域
        layout.setStretch(1, 0)   # 按钮
        layout.setStretch(2, 9)    # 表格
        layout.setStretch(3, 1)    # 说明

    def calculate(self):
        # 获取并清理输入
        capital_text = self.capital_input.text().strip()
        risk_text = self.risk_input.text().strip()
        
        # 增加空值校验
        if not capital_text or not risk_text:
            QMessageBox.warning(self, "输入错误", "请输入完整的数值")
            return

        try:
            # 转换前移除非数字字符
            capital = float(capital_text.replace(',', ''))
            risk_percent = float(risk_text.replace('%', '')) / 100
            if not 0 < risk_percent <= 1:  # 新增范围检查
                raise ValueError("风险比例需在0-100%之间")
        except ValueError as e:
            QMessageBox.warning(self, "输入错误", str(e))
            return

        self.table.setRowCount(0)

        for product in self.products:
            # 添加类型安全检查（关键修复）
            if not isinstance(product, dict):
                print(f"无效的产品数据: {product}")
                continue
                
            # 确保字典包含必要字段
            required_keys = ['margin', 'stoploss', 'multiplier']
            if not all(k in product for k in required_keys):
                print(f"缺失必要字段: {product}")
                continue

            # 修改后的最大开仓量计算
            risk_capital = capital * risk_percent
            margin = product['margin'] or 1
            max_lots = int(risk_capital / margin)
            
            # 建议开仓量计算保持不变
            suggested = max_lots // 3
            
            # 计算风险金额（仅用于显示）
            risk_per_lot = product['stoploss'] * product['multiplier']

            # 添加表格行（新增保证金列）
            row = self.table.rowCount()
            self.table.insertRow(row)
            
            # 调整列顺序（交换品种和保证金位置）
            self.table.setItem(row, 0, QTableWidgetItem(product['name']))      # 第一列：品种
            self.table.setItem(row, 1, QTableWidgetItem(str(product['margin'])))  # 第二列：保证金
            self.table.setItem(row, 2, QTableWidgetItem(f"{risk_per_lot:.2f}元")) 
            self.table.setItem(row, 3, QTableWidgetItem(str(suggested)))
            self.table.setItem(row, 4, QTableWidgetItem(str(max_lots)))

        # 添加表格刷新（新增）
        self.table.viewport().update()


        # 添加全局字体设置
    def connect_tq(self):
        """连接天勤账户"""     
        try:
            self.connect_btn.setEnabled(False)  # 禁用按钮防止重复点击
            self.connect_btn.setText("连接中...")
            
            # 创建后台线程
            from threading import Thread
            Thread(target=self._connect_thread, daemon=True).start()
            
        except Exception as e:
            self.connect_btn.setEnabled(True)
            QMessageBox.critical(self, "错误", f"启动连接失败: {str(e)}")

    def disconnect_tq(self):
        """断开天勤连接"""
        try:
            # 修改为更安全的空值检查
            if getattr(self, 'api', None) is not None:
                self.api.close()  # 仅当api存在时关闭
                self.api = None
                
            # 移除冗余的tq_account检查
            self.tq_account = None
            
            # 强制解除旧连接（关键修复）
            try:
                self.connect_btn.clicked.disconnect()
            except TypeError:
                pass
            
            # 完整重置UI状态
            self.connection_signal.emit("连接天勤账户", False)
            self.capital_input.clear()
            self.table.setRowCount(0)
            print("已成功断开连接")
            
        except Exception as e:
            print(f"断开异常: {str(e)}")
            self.connection_signal.emit("连接异常！", False)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 样式设置应该在窗口创建前完成（关键）
    app.setStyle(QStyleFactory.create("WindowsVista"))
    app.setFont(QFont("微软雅黑", 9))
    app.setStyleSheet("""
        * {
            font-family: "微软雅黑", "Consolas";
        }
        QLineEdit, QTableWidget, QLabel {
            font: 10pt "Consolas", "微软雅黑";
        }
    """)
    app.setWindowIcon(QIcon('app.png'))
    window = CapitalManager()
    window.show()
    sys.exit(app.exec_())